From 6317fd35294da0cb58c464612e1bcdf33a1192c6 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Thu, 6 Feb 2020 17:10:13 +0100 Subject: [PATCH] Replace last users of gtk_icon_paintable_download_texture () These now render the paintable to a cairo surface and convert that to a texture. This is sort of a hack, but its only used in two special cases internally and in two hacky test apps. --- gtk/gtkmountoperation.c | 35 +++++++++++++++++-- gtk/gtkwindow.c | 42 +++++++++++++++++++---- tests/testclipboard2.c | 44 +++++++++++++++++++++++- tests/testdnd2.c | 71 +++++++++++++++++++++++++++++++++------ testsuite/gtk/icontheme.c | 60 +-------------------------------- 5 files changed, 172 insertions(+), 80 deletions(-) diff --git a/gtk/gtkmountoperation.c b/gtk/gtkmountoperation.c index 07fc81c5c3..6efba15c59 100644 --- a/gtk/gtkmountoperation.c +++ b/gtk/gtkmountoperation.c @@ -55,7 +55,8 @@ #include "gtkgestureclick.h" #include "gtkmodelbuttonprivate.h" #include "gtkpopover.h" - +#include "gtksnapshot.h" +#include "gdktextureprivate.h" #include /** @@ -1137,6 +1138,36 @@ diff_sorted_arrays (GArray *array1, } } +static GdkTexture * +render_paintable_to_texture (GdkPaintable *paintable) +{ + GtkSnapshot *snapshot; + GskRenderNode *node; + int width, height; + cairo_surface_t *surface; + cairo_t *cr; + GdkTexture *texture; + + width = gdk_paintable_get_intrinsic_width (paintable); + height = gdk_paintable_get_intrinsic_height (paintable); + + surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); + + snapshot = gtk_snapshot_new (); + gdk_paintable_snapshot (paintable, snapshot, width, height); + node = gtk_snapshot_free_to_node (snapshot); + + cr = cairo_create (surface); + gsk_render_node_draw (node, cr); + cairo_destroy (cr); + + gsk_render_node_unref (node); + + texture = gdk_texture_new_for_surface (surface); + cairo_surface_destroy (surface); + + return texture; +} static void add_pid_to_process_list_store (GtkMountOperation *mount_operation, @@ -1180,7 +1211,7 @@ add_pid_to_process_list_store (GtkMountOperation *mount_operation, 24, 1, gtk_widget_get_direction (GTK_WIDGET (mount_operation->priv->dialog)), 0); - texture = gtk_icon_paintable_download_texture (icon); + texture = render_paintable_to_texture (GDK_PAINTABLE (icon)); g_object_unref (icon); } diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index 882b0048fa..c945468e7e 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -3999,6 +3999,37 @@ icon_size_compare (GdkTexture *a, return area_a - area_b; } +static GdkTexture * +render_paintable_to_texture (GdkPaintable *paintable) +{ + GtkSnapshot *snapshot; + GskRenderNode *node; + int width, height; + cairo_surface_t *surface; + cairo_t *cr; + GdkTexture *texture; + + width = gdk_paintable_get_intrinsic_width (paintable); + height = gdk_paintable_get_intrinsic_height (paintable); + + surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); + + snapshot = gtk_snapshot_new (); + gdk_paintable_snapshot (paintable, snapshot, width, height); + node = gtk_snapshot_free_to_node (snapshot); + + cr = cairo_create (surface); + gsk_render_node_draw (node, cr); + cairo_destroy (cr); + + gsk_render_node_unref (node); + + texture = gdk_texture_new_for_surface (surface); + cairo_surface_destroy (surface); + + return texture; +} + static GList * icon_list_from_theme (GtkWindow *window, const gchar *name) @@ -4009,6 +4040,7 @@ icon_list_from_theme (GtkWindow *window, GtkCssValue *value; GtkIconTheme *icon_theme; GtkIconPaintable *info; + GdkTexture *texture; gint *sizes; gint i; @@ -4036,14 +4068,10 @@ icon_list_from_theme (GtkWindow *window, sizes[i], priv->scale, gtk_widget_get_direction (GTK_WIDGET (window)), 0); - if (info) - { - GdkTexture *texture = gtk_icon_paintable_download_texture (info); - if (texture) - list = g_list_insert_sorted (list, texture, (GCompareFunc) icon_size_compare); - g_object_unref (info); - } + texture = render_paintable_to_texture (GDK_PAINTABLE (info)); + list = g_list_insert_sorted (list, texture, (GCompareFunc) icon_size_compare); + g_object_unref (info); } g_free (sizes); diff --git a/tests/testclipboard2.c b/tests/testclipboard2.c index 35b58e5167..edb5ae51b3 100644 --- a/tests/testclipboard2.c +++ b/tests/testclipboard2.c @@ -17,6 +17,48 @@ #include +static GdkTexture * +render_paintable_to_texture (GdkPaintable *paintable) +{ + GtkSnapshot *snapshot; + GskRenderNode *node; + int width, height; + cairo_surface_t *surface; + cairo_t *cr; + GdkTexture *texture; + GBytes *bytes; + + width = gdk_paintable_get_intrinsic_width (paintable); + height = gdk_paintable_get_intrinsic_height (paintable); + + surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); + + snapshot = gtk_snapshot_new (); + gdk_paintable_snapshot (paintable, snapshot, width, height); + node = gtk_snapshot_free_to_node (snapshot); + + cr = cairo_create (surface); + gsk_render_node_draw (node, cr); + cairo_destroy (cr); + + gsk_render_node_unref (node); + + bytes = g_bytes_new_with_free_func (cairo_image_surface_get_data (surface), + cairo_image_surface_get_height (surface) + * cairo_image_surface_get_stride (surface), + (GDestroyNotify) cairo_surface_destroy, + cairo_surface_reference (surface)); + texture = gdk_memory_texture_new (cairo_image_surface_get_width (surface), + cairo_image_surface_get_height (surface), + GDK_MEMORY_DEFAULT, + bytes, + cairo_image_surface_get_stride (surface)); + g_bytes_unref (bytes); + cairo_surface_destroy (surface); + + return texture; +} + static void clipboard_changed_cb (GdkClipboard *clipboard, GtkWidget *stack) @@ -292,7 +334,7 @@ get_button_list (GdkClipboard *clipboard, 48, 1, gtk_widget_get_direction (box), 0); - texture = gtk_icon_paintable_download_texture (icon); + texture = render_paintable_to_texture (GDK_PAINTABLE (icon)); g_value_take_object (&value, gdk_pixbuf_get_from_texture (texture)); g_object_unref (texture); g_object_unref (icon); diff --git a/tests/testdnd2.c b/tests/testdnd2.c index f419c975bf..e98ac71499 100644 --- a/tests/testdnd2.c +++ b/tests/testdnd2.c @@ -6,6 +6,53 @@ #include #endif +static GdkTexture * +render_paintable_to_texture (GdkPaintable *paintable) +{ + GtkSnapshot *snapshot; + GskRenderNode *node; + int width, height; + cairo_surface_t *surface; + cairo_t *cr; + GdkTexture *texture; + GBytes *bytes; + + width = gdk_paintable_get_intrinsic_width (paintable); + if (width == 0) + width = 32; + + height = gdk_paintable_get_intrinsic_height (paintable); + if (height == 0) + height = 32; + + surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); + + snapshot = gtk_snapshot_new (); + gdk_paintable_snapshot (paintable, snapshot, width, height); + node = gtk_snapshot_free_to_node (snapshot); + + cr = cairo_create (surface); + gsk_render_node_draw (node, cr); + cairo_destroy (cr); + + gsk_render_node_unref (node); + + bytes = g_bytes_new_with_free_func (cairo_image_surface_get_data (surface), + cairo_image_surface_get_height (surface) + * cairo_image_surface_get_stride (surface), + (GDestroyNotify) cairo_surface_destroy, + cairo_surface_reference (surface)); + texture = gdk_memory_texture_new (cairo_image_surface_get_width (surface), + cairo_image_surface_get_height (surface), + GDK_MEMORY_DEFAULT, + bytes, + cairo_image_surface_get_stride (surface)); + g_bytes_unref (bytes); + cairo_surface_destroy (surface); + + return texture; +} + static GdkTexture * get_image_texture (GtkImage *image, int *out_size) @@ -13,7 +60,7 @@ get_image_texture (GtkImage *image, GtkIconTheme *icon_theme; const char *icon_name; int width = 48; - GdkPaintable *paintable; + GdkPaintable *paintable = NULL; GdkTexture *texture = NULL; GtkIconPaintable *icon; @@ -21,29 +68,28 @@ get_image_texture (GtkImage *image, { case GTK_IMAGE_PAINTABLE: paintable = gtk_image_get_paintable (image); - if (GDK_IS_TEXTURE (paintable)) - { - *out_size = gdk_paintable_get_intrinsic_width (paintable); - texture = g_object_ref (GDK_TEXTURE (paintable)); - } + break; case GTK_IMAGE_ICON_NAME: icon_name = gtk_image_get_icon_name (image); icon_theme = gtk_icon_theme_get_for_display (gtk_widget_get_display (GTK_WIDGET (image))); - *out_size = width; icon = gtk_icon_theme_lookup_icon (icon_theme, icon_name, NULL, width, 1, gtk_widget_get_direction (GTK_WIDGET (image)), 0); - if (icon) - texture = gtk_icon_paintable_download_texture (icon); - g_object_unref (icon); + paintable = GDK_PAINTABLE (icon); + break; default: g_warning ("Image storage type %d not handled", gtk_image_get_storage_type (image)); } + if (paintable) + texture = render_paintable_to_texture (paintable); + + g_object_unref (paintable); + return texture; } @@ -238,11 +284,14 @@ update_source_icon (GtkDragSource *source, int hot_x, hot_y; int size = 48; + if (widget == NULL) + return; + icon = gtk_icon_theme_lookup_icon (gtk_icon_theme_get_for_display (gtk_widget_get_display (widget)), icon_name, NULL, size, 1, - gtk_widget_get_direction (widget), + gtk_widget_get_direction (widget) , 0); switch (hotspot) { diff --git a/testsuite/gtk/icontheme.c b/testsuite/gtk/icontheme.c index 4cbce215bc..5c3b6cd008 100644 --- a/testsuite/gtk/icontheme.c +++ b/testsuite/gtk/icontheme.c @@ -93,14 +93,7 @@ assert_icon_lookup_size (const char *icon_name, g_assert (gtk_icon_paintable_get_filename (info) == NULL); } - if (pixbuf_size > 0) - { - GdkTexture *texture; - - texture = gtk_icon_paintable_download_texture (info); - g_assert_cmpint (gdk_texture_get_width (texture), ==, pixbuf_size); - g_object_unref (texture); - } + g_assert_cmpint (gdk_paintable_get_intrinsic_width (GDK_PAINTABLE (info)), ==, size); g_object_unref (info); } @@ -711,56 +704,6 @@ test_inherit (void) "/icons2/scalable/one-two-symbolic-rtl.svg"); } -static void -test_nonsquare_symbolic (void) -{ - gint width, height; - GtkIconTheme *icon_theme; - GtkIconPaintable *info; - GFile *file; - GIcon *icon; - GError *error = NULL; - GdkTexture *texture; - gchar *path = g_build_filename (g_test_get_dir (G_TEST_DIST), - "icons", - "scalable", - "nonsquare-symbolic.svg", - NULL); - - /* load the original image for reference */ - GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file (path, &error); - g_assert_no_error (error); - g_assert_nonnull (pixbuf); - - width = gdk_pixbuf_get_width (pixbuf); - height = gdk_pixbuf_get_height (pixbuf); - g_assert_cmpint (width, !=, height); - - /* now load it through GtkIconTheme */ - icon_theme = gtk_icon_theme_get_for_display (gdk_display_get_default ()); - file = g_file_new_for_path (path); - icon = g_file_icon_new (file); - info = gtk_icon_theme_lookup_by_gicon (icon_theme, icon, - height, 1, GTK_TEXT_DIR_NONE, 0); - g_assert_nonnull (info); - - g_object_unref (pixbuf); - texture = gtk_icon_paintable_download_texture (info); - - /* we are loaded successfully */ - g_assert_nonnull (texture); - - /* the original dimensions have been preserved */ - g_assert_cmpint (gdk_texture_get_width (texture), ==, width); - g_assert_cmpint (gdk_texture_get_height (texture), ==, height); - - g_free (path); - g_object_unref (texture); - g_object_unref (file); - g_object_unref (icon); - g_object_unref (info); -} - int main (int argc, char *argv[]) { @@ -777,7 +720,6 @@ main (int argc, char *argv[]) g_test_add_func ("/icontheme/size", test_size); g_test_add_func ("/icontheme/list", test_list); g_test_add_func ("/icontheme/inherit", test_inherit); - g_test_add_func ("/icontheme/nonsquare-symbolic", test_nonsquare_symbolic); return g_test_run(); } -- 2.30.2